package com.junzhiit.nengji.app.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.junzhiit.nengji.app.service.FunctionService;
import com.junzhiit.nengji.app.web.exception.RoleNotFoundException;
import com.junzhiit.nengji.app.web.util.Constants;
import com.junzhiit.nengji.app.web.vo.FunctionListVO;
import com.junzhiit.nengji.app.web.vo.MenuVO;
import com.junzhiit.nengji.app.web.vo.ResultVO;
import com.junzhiit.nengji.app.web.vo.SystemUserSessionVO;
import com.junzhiit.nengji.app.web.vo.TreeNodeVO;
import com.junzhiit.nengji.bo.FunctionBO;
import com.junzhiit.nengji.dao.FunctionDAO;
import com.junzhiit.nengji.dao.RoleDAO;
import com.junzhiit.nengji.dao.RoleFunctionDAO;
import com.junzhiit.nengji.dao.SystemUserDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Function;
import com.junzhiit.nengji.model.Role;
import com.junzhiit.nengji.model.RoleFunction;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.SystemUserType;

@Service
public class FunctionServiceImpl extends BaseServiceImpl implements FunctionService {

	@Autowired
	private FunctionDAO functionDAO;

	@Autowired
	private RoleFunctionDAO roleFunctionDAO;

	@Autowired
	private RoleDAO roleDAO;

	@Autowired
	SystemUserDAO systemUserDAO;

	@Autowired
	SystemUserCacheDAO systemUserCacheDAO;

	@Override
	public ResultVO findByPlatform(Integer platform) {
		ResultVO result = new ResultVO();
		List<Function> list = functionDAO.findByPlatform(platform);
		TreeNodeVO data=tree(list);
		result.setData(data);
		return result;
	}

	@Override
	public ResultVO findBySystemUserId(FunctionListVO functionListVO) {
		ResultVO result = new ResultVO();

		Role role = roleDAO.query(functionListVO.getRoleId());
		if (role == null) {
			throw new RoleNotFoundException("该角色不存在！");
		}

		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(functionListVO.getSessionId()), SystemUserSessionVO.class);
		List<Function> list = new ArrayList<Function>();
		if (systemUserSessionVO.getLoginType().equals(SystemUserType.INTERNAL.toIntStatus())) {
			if (functionListVO.getPlatform().equals(systemUserSessionVO.getLoginType())) {
				if(systemUserSessionVO.getIsSys()==Is.NO.toIntValue()){
					list = systemUserDAO.getSystemUserFunctions(systemUserSessionVO.getSystemUserId());
				}else if(systemUserSessionVO.getIsSys()==Is.YES.toIntValue()){
					list = functionDAO.findByPlatform(functionListVO.getPlatform());
				}
			} else {
				list = functionDAO.findByPlatform(functionListVO.getPlatform());
			}
		} else {
			list = systemUserDAO.getSystemUserFunctions(systemUserSessionVO.getSystemUserId());
		}

		List<RoleFunction> rfs = roleFunctionDAO.getRoleFunction(functionListVO.getRoleId());
		List<FunctionBO> fbs = new ArrayList<FunctionBO>();
		Set<String> ids = rfs.stream().map(RoleFunction::getFunctionId).collect(Collectors.toSet());

		for (Function item : list) {
			FunctionBO fb = new FunctionBO();
			BeanUtils.copyProperties(item, fb);
			if (ids.contains(item.getId())) {
				fb.setIsSelect(1);
			} else {
				fb.setIsSelect(0);
			}
			fbs.add(fb);
		}

		TreeNodeVO data=tree(fbs);
		result.setData(data);
		
		return result;
	}

	private TreeNodeVO tree(List<? extends Function> dataList){
		// 节点列表（散列表，用于临时存储节点对象）  
		HashMap<String, TreeNodeVO> nodeList = new HashMap<String, TreeNodeVO>();  
		// 根节点  
		TreeNodeVO root = new TreeNodeVO();
		root.setLabel(Constants.ROOT_VALUE);
		root.setChildren(new ArrayList<TreeNodeVO>());


		// 根据结果集构造节点列表（存入散列表）  
		for (Function function : dataList) { 
			TreeNodeVO node = new TreeNodeVO();
			BeanUtils.copyProperties(function, node);
			node.setLabel(function.getName());
			
			MenuVO menuVO = new MenuVO();
			BeanUtils.copyProperties(function, menuVO);
			node.setData(menuVO);
			
			node.setChildren(new ArrayList<TreeNodeVO>());
			nodeList.put(node.getId(), node);  
		}

		// 构造无序的多叉树
		Set<Entry<String, TreeNodeVO>> entrySet = nodeList.entrySet();  
		for (Iterator<Entry<String, TreeNodeVO>> it = entrySet.iterator(); it.hasNext();) {  
			TreeNodeVO treeNodeVO= it.next().getValue();

			if(Constants.ROOT_VALUE.equals(treeNodeVO.getParentId())){
				root.getChildren().add(treeNodeVO);
			}else{
				nodeList.get(treeNodeVO.getParentId()).getChildren().add(treeNodeVO); 
			}

		}
		
		// 对多叉树进行横向排序
		root.sortChildren();


		return root;
	}
}
